/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Interface;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
import moteur.carte.Arc;
import moteur.carte.Chemin;
import moteur.carte.Clickable;
import moteur.carte.editor.Graphe;
import moteur.carte.Lac;
import moteur.carte.Riviere;
import moteur.carte.Ville;
import moteur.carte.editor.ControllerGraphe;
import moteur.partie.Partie;

/**
 *
 * @author nlupins
 */
public class AffichageCarte extends JPanel {

    private Clickable selected = null;
    private Quadtree quad = new Quadtree();
    private Graphe graphe;
    private IG ig;
    private boolean editing = false;
    private int currentElement = 0; // sert pour le choix de l'élément à ajouter
    // {0=>Ville, 1=>Chemin, 2=>Riviere, 3=>Lac}
    private ControllerGraphe cm = new ControllerGraphe();

    /**
     * 
     */
    public AffichageCarte(IG ig) {
        setOpaque(false);
        this.ig = ig;

        graphe = Partie.getInstance().getG();
        fillQuadtree();

        this.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
                //System.out.println(Integer.toString(e.getX()) +" "+ Integer.toString(e.getY()));
                float tmp = 1.0f / 1024.0f;
                //System.out.println(e.getX()*tmp +" "+ e.getY()*tmp);
                selected = quad.getClickable(e.getX() * tmp, e.getY() * tmp);
                if (selected != null) {
                    //System.out.println(selected.toString());
                    AffichageCarte.this.ig.doSomething();
                    repaint();
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
    }

    public AffichageCarte(IG ig, boolean edit) {
        setOpaque(false);
        this.ig = ig;
        editing = edit;

        graphe = Partie.getInstance().getG();
        cm.setGraphe(graphe);
        fillQuadtree();

        this.addMouseListener(new MouseListener() {

            @Override
            @SuppressWarnings("static-access")
            public void mouseClicked(MouseEvent e) {
                Clickable c;
                //cm.setGraphe(graphe) ;
                float tmp = 1.0f / 1024.0f;
                float f = 0.98f;

                switch (currentElement) {

                    case 0:
                         c= null;
                        if (cm.possibleAddCapitale()) {
                            c = cm.addCapitale(e.getX() * tmp, e.getY() * tmp);
                            float k = f;
                            float x=c.getX(); float y=c.getY();
                            while (!quad.addClickable(c)) {
                                c.setX(x + (float) ((Math.random()-0.5f) * (1 - k)));
                                c.setY(y + (float) ((Math.random()-0.5f) * (1 - k)));
                                k = k * f;
                            }
                        } else {
                            if (cm.possibleAddVille(graphe.nbMaxVille)) {
                                c = cm.addVille(e.getX() * tmp, e.getY() * tmp);
                                float k = f;
                            float x=c.getX(); float y=c.getY();
                            while (!quad.addClickable(c)) {
                                c.setX(x + (float) ((Math.random()-0.5f) * (1 - k)));
                                c.setY(y + (float) ((Math.random()-0.5f) * (1 - k)));
                                k = k * f;
                            }

                            }
                        }
                        if (cm.getGraphe().getListeVille().size() == cm.getGraphe().nbMaxVille) {
                            cm.followTheListe();
                            currentElement++;
                        }
                        repaint();
                        break;
                    case 1:
                        c = null;
                        if (cm.possibleAddChemin(graphe.nbMaxChemin)) {

                            if (cm.thereIsVilleHere(e.getX() * tmp, e.getY() * tmp)) {
                                c = cm.addChemin(cm.whichVille(e.getX() * tmp, e.getY() * tmp));
                            }

                            if (c != null){
                                c.setX((((Arc)c).getOrig().getX()+((Arc)c).getDest().getX())*0.5f);
                                c.setY((((Arc)c).getOrig().getY()+((Arc)c).getDest().getY())*0.5f);
                            float k = f;
                            float x=c.getX(); float y=c.getY();
                            while (!quad.addClickable(c)) {
                                c.setX(x + (float) ((Math.random()-0.5f) * (1 - k)));
                                c.setY(y + (float) ((Math.random()-0.5f) * (1 - k)));
                                k = k * f;
                            }
                            }
                        }
                        if (cm.getGraphe().getListeChemin().size() == cm.getGraphe().nbMaxChemin) {
                            cm.followTheListe();
                            currentElement++;
                        }
                        repaint();
                        break;
                    case 2:
                        c= null;
                        if (cm.possibleAddRiviere(graphe.nbMaxRiviere)) {
                            if (cm.thereIsVilleHere(e.getX() * tmp, e.getY() * tmp)) {
                                c = cm.addRiviere(cm.whichVille(e.getX() * tmp, e.getY() * tmp));
                            }
                            if (c != null){
                                c.setX((((Arc)c).getOrig().getX()+((Arc)c).getDest().getX())*0.5f);
                                c.setY((((Arc)c).getOrig().getY()+((Arc)c).getDest().getY())*0.5f);
                            float k = f;
                            float x=c.getX(); float y=c.getY();
                            while (!quad.addClickable(c)) {
                                c.setX(x + (float) ((Math.random()-0.5f) * (1 - k)));
                                c.setY(y + (float) ((Math.random()-0.5f) * (1 - k)));
                                k = k * f;
                            }
                            }
                        }
                        if (cm.getGraphe().getListeRiviere().size() == cm.getGraphe().nbMaxRiviere) {
                            cm.followTheListe();
                            currentElement++;
                        }
                        repaint();
                        break;
                    case 3:
                        c = null;
                        if (cm.possibleAddLac(graphe.nbMaxLac)) {
                            if (cm.thereIsVilleHere(e.getX() * tmp, e.getY() * tmp)) {
                              c = cm.addLac(cm.whichVille(e.getX() * tmp, e.getY() * tmp));
                            }

                            if (c != null){
                                int i = 0;
                                float x =0 , y=0;
                                for(Ville v: ((Lac)c).getVilles()){
                                i++;
                                x += v.getX();
                                y += v.getY();
                                }
                                x = x/i;
                                y = y/i;
                                c.setX(x);
                                c.setY(y);
                            float k = f;

                            while (!quad.addClickable(c)) {
                                c.setX(x + (float) ((Math.random()-0.5f) * (1 - k)));
                                c.setY(y + (float) ((Math.random()-0.5f) * (1 - k)));
                                k = k * f;
                            }
                            }

                        }
                        if (cm.getGraphe().getListeLac().size() == cm.getGraphe().nbMaxLac) {
                            cm.followTheListe();
                            currentElement++;
                        }
                        repaint();
                        break;
                    default:
                        break;
                }
                if ( cm.getGraphe().getListeVille().size() == cm.getGraphe().nbMaxVille &&
                        cm.getGraphe().getListeChemin().size() == cm.getGraphe().nbMaxChemin &&
                        cm.getGraphe().getListeRiviere().size() == cm.getGraphe().nbMaxRiviere &&
                        cm.getGraphe().getListeLac().size() == cm.getGraphe().nbMaxLac )
                    cm.updateRoads();
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

    }

    /**
     *
     * @return
     */
    public Clickable getSelected() {
        return selected;
    }

    private void fillQuadtree() {
        if (graphe != null) {
            for (Arc l : graphe.getListeChemin()) {
                quad.addClickable(l);
            }
            for (Lac l : graphe.getListeLac()) {
                quad.addClickable(l);
            }
            for (Arc l : graphe.getListeRiviere()) {
                quad.addClickable(l);
            }
            for (Ville l : graphe.getListeVille()) {
                quad.addClickable(l);
            }

        }

    }

    @Override
    //@SuppressWarnings({"static-access", "empty-statement"})
    public void paint(Graphics g) {

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        if (graphe != null) {


            for (Lac l : graphe.getListeLac()) {
                l.draw(g2, 1024);
            }
            for (Riviere l : graphe.getListeRiviere()) {
                l.draw(g2, 1024);
            }
            for (Chemin l : graphe.getListeChemin()) {
                l.draw(g2, 1024);

            }
            for (Ville l : graphe.getListeVille()) {
                l.draw(g2, 1024);
            }
        }
        if (selected != null) {
            g2.setColor(Color.red);
            int w = (int) (selected.getWidth() * 1024);
            g2.drawRect((int) (selected.getX() * 1024), (int) (selected.getY() * 1024), w, w);
        }

        if(editing){quad.draw(g2, 0, 1, 0, 1, 1024);}

        /* test or not test
        g2.fillRect(0, 0, 30, 30);

        //test Lac vite fait
        g2.setColor(Color.blue);
        Polygon p = new Polygon();
        p.addPoint(35, 35);
        p.addPoint(45, 200);
        p.addPoint(400, 100);
        g2.fillPolygon(p);

        // test chemin vite fait
        g2.setColor(Color.GREEN);
        drawChemin(g, 20, 40, 65, 300, 10);
        drawChemin(g, 300, 40, 65, 28, 10);

        Lac.testRemoteDraw(g2, 1024);
        //*/
    }

    @Override
    public void repaint() {
        super.repaint();
    }

   

    public void setCurrentElement(int val) {
        currentElement = val;
    }

    public int getCurrentElement() {
        return currentElement;
    }

    public boolean getEditing() {
        return editing;
    }
}
